package com.lagou.factory;

import com.lagou.dao.AccountDao;
import com.lagou.service.TransferService;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <pre>
 * 描述：TODO
 * </pre>
 *
 * @类名：com.lagou.factory.BeanFactory
 * @作者 mengwei
 * 创建日期：2020/10/13 15:34
 */
public class BeanFactory {

    /**
     * 任务一：读取解析xml，通过反射技术实例化对象并且存出待用（map集合）
     * 任务二：对我提供实例对象的接口
     */

    private static Map<String,Object> map=new HashMap<String,Object>();

    static {
        /**
         * 初始化的时候解析xml，通过反射实例化对象，并且放入map
         */

        InputStream resourceAsStream = BeanFactory.class.getClassLoader().getResourceAsStream("beans.xml");
        SAXReader saxReader = new SAXReader();
        try {
            Document document = saxReader.read(resourceAsStream);
            List<Element> beans = document.getRootElement().selectNodes("//bean");
//            遍历创建bean节点对象，并且添加到map中
            for (Element element : beans) {
                map.put(element.attributeValue("id"),Class.forName(element.attributeValue("class")).newInstance());
            }

//            解析property属性，并且将其中定义的值注入到bean中
            List<Element> properties = document.getRootElement().selectNodes("//property");

//    <bean id="transferServlet" class="com.lagou.servlet.TransferServlet">
//        <property name ="TransferService" ref="transferService"/>
//    </bean>
        for (Element property : properties) {
                Object parmObj = map.get(property.attributeValue("ref"));
                String parentId = property.getParent().attributeValue("id");
                Object parentObj = map.get(parentId);
                Method[] methods = parentObj.getClass().getMethods();
                for (Method method : methods) {
                    if (method.getName().equals("set"+property.attributeValue("name"))){
//                        如果property对应的设置方法，使用反射进行设置
                        method.invoke(parentObj,parmObj);
                        break;
                    }
                }
//                map.put(parentId,parentObj);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    public static Object getBean(String beanId) {
        return map.get(beanId);
    }
}
